﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Security;
using System.IO;
using System.Xml.Linq;
using System.Security.Permissions;

namespace SPIconIntegration.Code.TimerJobs {
    class InstallIconTimerJob : SPJobDefinition {
         /// <summary>
        /// Filepath for the docicon.xml file
        /// </summary>
        private const string filePath = "TEMPLATE\\XML\\DOCICON.XML";
 
        /// <summary>
        /// The property key for the delete property
        /// </summary>
        private const string deleteKey = "Icon_Installation_Deletekey";
 
        /// <summary>
        /// The property key for the feature property
        /// </summary>
        private const string featureKey = "Icon_Installation_Featurekey";
 
        private bool PerformDelete
        {
            get
            {
                return Properties.ContainsKey(deleteKey) && Convert.ToBoolean(Properties[deleteKey], CultureInfo.InvariantCulture);
            }
            set
            {
                if (Properties.ContainsKey(deleteKey)){
                    Properties[deleteKey] = value.ToString();
                }
                else{
                    Properties.Add(deleteKey, value.ToString());
                }
            }
        }
 
        private Guid FeatureId
        {
            get
            {
                if (Properties.ContainsKey(featureKey))
                {
                    return new Guid(Properties[featureKey].ToString());
                }
                
                return Guid.Empty;
            }
            set
            {
                if (Properties.ContainsKey(featureKey)){
                    Properties[featureKey] = value.ToString();
                }
                else{
                    Properties.Add(featureKey, value.ToString());
                }
            }
 
        }
 
        private string IconExtension
        {
            get
            {
                SPFeatureDefinition def = Farm.FeatureDefinitions[FeatureId];
                return def.Properties["IconExtension"].Value;
            }
        }
 
        private string IconUrl
        {
            get
            {
                SPFeatureDefinition def = Farm.FeatureDefinitions[FeatureId];
                return def.Properties["IconUrl"].Value;
            }
        }


        /// <summary>
        /// Gets the doc icon file.
        /// </summary>
        /// <value>The doc icon file.</value>
        public static string DocIconFile
        {
            get
            {
                return SPUtility.GetGenericSetupPath(filePath);
            }
        }

        public InstallIconTimerJob()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InstallIconTimerJob"/> class.
        /// </summary>
        /// <param name="webApplication">The web application.</param>
        /// <param name="featureId">The feature id.</param>
        /// <param name="performDelete">if set to <c>true</c> perform delete.</param>
        public InstallIconTimerJob(SPWebApplication webApplication, Guid featureId, bool performDelete):base("Icon Installer", webApplication, null, SPJobLockType.None)
        {
            PerformDelete = performDelete;
            FeatureId = featureId;            
        }

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void Execute(Guid targetInstanceId)
        {
            base.Execute(targetInstanceId);
            ChangeDocIconFile();
        }
 
        private void ChangeDocIconFile()
        {
            if (!File.Exists(DocIconFile))
            {
                throw new FileNotFoundException("The DocIcon file does not exist on the server");
            }

            var doc = XDocument.Load(DocIconFile);

            var element = from b in doc.Element("DocIcons").Element("ByExtension").Elements("Mapping")
                          where b.Attribute("Key").Value.ToUpperInvariant() == IconExtension.ToUpperInvariant()
                          select b;

            bool containsElement = (element.Count() > 0);

            if (PerformDelete)
            {
                if (containsElement)
                {
                    element.Remove();
                    doc.Save(DocIconFile);
                }
            }
            else
            {
                if (!containsElement)
                {
                    var iconElement = new XElement("Mapping");
                    iconElement.SetAttributeValue("Key", IconExtension);
                    iconElement.SetAttributeValue("Value", IconUrl);

                    doc.Element("DocIcons").Element("ByExtension").Add(iconElement);
                    doc.Save(DocIconFile);
                }
            }
        }
    }
}
